﻿using System;

namespace Teal.Compiler {

    ///// <summary>
    ///// 提供语义解析使用的辅助函数。
    ///// </summary>
    //public static partial class ResolveHelper {

    //    /// <summary>
    //    /// 将指定的表达式转换为指定的类型。
    //    /// </summary>
    //    /// <param name="expression">要转换的表达式。</param>
    //    /// <param name="targetType">转换的目标类型。</param>
    //    /// <param name="allowExplicitCast">是否允许显式转换。</param>
    //    /// <param name="srcNode">引发本次操作的源节点，主要用于报错。</param>
    //    /// <returns>返回转换表达式。</returns>
    //    public static Expression convertTo(Expression expression, TypeReference targetType, State explicitCast, Node srcNode) {

    //        // 加速转换相同类型。
    //        if (expression.resolvedType == targetType) {
    //            return expression;
    //        }

    //        return applyConversion(expression, targetType, classifyConversion(expression, expression.resolvedType, targetType), explicitCast, srcNode);
    //    }

    //    /// <summary>
    //    /// 获取将指定表达式到目标类型的转换类型。
    //    /// </summary>
    //    /// <param name="expression">要转换的表达式。</param>
    //    /// <param name="to">要转换的目标类型。</param>
    //    /// <returns>返回转换的类型。</returns>
    //    public static ConversionType classifyConversion(Expression fromExpression, TypeReference from, TypeReference to) {

    //        // 进行隐式转换。
    //        var result = classifyImplicitConversion(fromExpression, from, to);
    //        if (result != ConversionType.none) {
    //            return result;
    //        }

    //        // 进行显示转换。
    //        return classifyExplicitConversion(fromExpression, from, to);
    //    }

    //    /// <summary>
    //    /// 使用指定的转换方式将指定表达式转为目标类型，并返回代表此操作的表达式。
    //    /// </summary>
    //    /// <param name="expression">要转换的表达式。</param>
    //    /// <param name="targetType">要转换的目标类型。</param>
    //    /// <param name="conversion">之前分析得到的转换类型。</param>
    //    /// <param name="srcNode">引发本次操作的源节点，主要用于报错。</param>
    //    /// <returns>返回代表转换操作的表达式。</returns>
    //    public static Expression applyConversion(Expression expression, TypeReference targetType, ConversionType conversionType, State explicitCast, Node srcNode) {
    //        switch (conversionType) {
    //            case ConversionType.identity:
    //                return expression;
    //            case ConversionType.implicitConstant:
    //                return applyImplicitConstantConversion((Constant)expression, targetType, srcNode);
    //            case ConversionType.implicitNumeric:
    //                Constant constantValue = expression as Constant;
    //                if (constantValue != null) {
    //                    return applyImplicitConstantConversion(constantValue, targetType, srcNode);
    //                }
    //                break;
    //            case ConversionType.none:
    //                Compiler.error(ErrorCode.none, String.Format("无法将类型“{0}”转换为“{1}”", expression.resolvedType.fullName, targetType.fullName), srcNode);
    //                return null;
    //            case ConversionType.implicitUserDefined:
    //                return applyUserDefinedConversion(expression, expression.resolvedType, targetType, true, srcNode);
    //            default:

    //                // 其它隐式转换不额外处理。
    //                if (conversionType < ConversionType.IMPILICT) {
    //                    break;
    //                }

    //                // 检测否允许使用显式转换。
    //                if (explicitCast == State.unset) {
    //                    Compiler.error(ErrorCode.none, String.Format("无法将类型“{0}”隐式转换为“{1}”（存在一个显示转换，是否缺少显式转换?）", expression.resolvedType.fullName, targetType.fullName), srcNode);
    //                    return null;
    //                }

    //                if (conversionType == ConversionType.explicitNumeric) {
    //                    goto case ConversionType.implicitNumeric;
    //                }

    //                if (conversionType == ConversionType.explicitUserDefined) {
    //                    return applyUserDefinedConversion(expression, expression.resolvedType, targetType, false, srcNode);
    //                }

    //                // 其它显式转换不额外处理。
    //                break;
    //        }

    //        return new ResolvedConversionExpression() {
    //            ignoreRuntimeError = explicitCast == State.off,
    //            value = expression,
    //            targetType = targetType,
    //            conversion = conversionType
    //        };
    //    }

    //    /// <summary>
    //    /// 返回将指定表达式到目标类型的隐式转换类型。
    //    /// </summary>
    //    /// <param name="fromExpression">要转换的来源表达式。</param>
    //    /// <param name="from">转换的来源类型。</param>
    //    /// <param name="to">转换的目标类型。</param>
    //    /// <returns>返回转换的类型。</returns>
    //    public static ConversionType classifyImplicitConversion(Expression fromExpression, TypeReference from, TypeReference to) {

    //        // * -> 自身
    //        // dynamic/object -> object/dynamic
    //        if (hasIdentityConversion(from, to)) {
    //            return ConversionType.identity;
    //        }

    //        // 常量 -> *
    //        if (hasImplicitConstantConversion(fromExpression as Constant, to)) {
    //            return ConversionType.implicitConstant;
    //        }

    //        // short -> int
    //        if (hasImplicitNumericConversion(from, to)) {
    //            return ConversionType.implicitNumeric;
    //        }

    //        // int* -> void*
    //        // ReferenceType -> void*
    //        if (hasImplicitPtrToVoidPtrConversion(from, to)) {
    //            return ConversionType.ptrToVoidPtr;
    //        }

    //        // ValueType -> object/dynamic
    //        if (hasBoxingConversion(from, to)) {
    //            return ConversionType.boxing;
    //        }

    //        // ReferenceType -> object/dynamic
    //        if (hasImplicitReferenceConversion(from, to)) {
    //            return ConversionType.implicitReference;
    //        }

    //        // 用户自定义的隐式转换
    //        if (hasUserDefinedConversion(from, to, true)) {
    //            return ConversionType.implicitUserDefined;
    //        }

    //        return ConversionType.none;
    //    }

    //    /// <summary>
    //    /// 返回将指定表达式到目标类型的显式转换类型。
    //    /// </summary>
    //    /// <param name="fromExpression">要转换的来源表达式。</param>
    //    /// <param name="from">转换的来源类型。</param>
    //    /// <param name="to">转换的目标类型。</param>
    //    /// <returns>返回转换的类型。</returns>
    //    public static ConversionType classifyExplicitConversion(Expression fromExpression, TypeReference from, TypeReference to) {

    //        // int -> short
    //        // char -> int
    //        // int -> char
    //        if (hasImplicitNumericConversion(to, from) || hasExplicitCharConversion(from, to) || hasExplicitCharConversion(to, from)) {
    //            return ConversionType.explicitNumeric;
    //        }

    //        // ValueType -> object
    //        if (hasBoxingConversion(to, from)) {
    //            return ConversionType.unboxing;
    //        }

    //        // ReferenceType -> ClassType
    //        // ReferenceType -> Interface
    //        // Interface -> ReferenceType
    //        if (hasImplicitReferenceConversion(to, from) || hasExplicitInterfaceConversion(from, to) || hasExplicitInterfaceConversion(to, from)) {
    //            return ConversionType.explicitReference;
    //        }

    //        // int* -> void*
    //        if (hasExplicitPtrToPtrConversion(from, to)) {
    //            return ConversionType.ptrToPtr;
    //        }

    //        // int* -> int
    //        if (hasExplicitIntegerToPtrConversion(from, to)) {
    //            return ConversionType.integerToPtr;
    //        }

    //        // int -> int*
    //        if (hasExplicitIntegerToPtrConversion(to, from)) {
    //            return ConversionType.ptrToInteger;
    //        }

    //        // 用户自定义的隐式转换
    //        if (hasUserDefinedConversion(from, to, false)) {
    //            return ConversionType.explicitUserDefined;
    //        }

    //        return ConversionType.none;
    //    }

    //    /// <summary>
    //    /// 判断是否存在从指定类型到目标类型的标识转换。
    //    /// </summary>
    //    /// <param name="from">转换的来源类型。</param>
    //    /// <param name="to">转换的目标类型。</param>
    //    /// <returns>如果存在则返回 true。</returns>
    //    private static bool hasIdentityConversion(TypeReference from, TypeReference to) {

    //        // T -> T
    //        if (from == to) {
    //            return true;
    //        }

    //        // object -> dynamic
    //        // dynamic -> object
    //        if (from == PredefinedTypes.System_Object) {
    //            if (to == PredefinedTypes.@dynamic) {
    //                return true;
    //            }
    //        } else if (from == PredefinedTypes.@dynamic) {
    //            if (to == PredefinedTypes.System_Object) {
    //                return true;
    //            }
    //        }

    //        return false;
    //    }

    //    /// <summary>
    //    /// 判断是否存在从指定类型到目标类型的常量转换。
    //    /// </summary>
    //    /// <param name="fromConstant">要转换的来源常量。</param>
    //    /// <param name="to">转换的目标类型。</param>
    //    /// <returns>如果存在则返回 true。</returns>
    //    private static bool hasImplicitConstantConversion(Constant fromConstant, TypeReference to) {

    //        // 由于常量值已知，因此常量允许从高位类型到低位类型的隐式转换。
    //        // 常量转换包括： 
    //        //   null as *
    //        //   string as char
    //        //   int as byte 
    //        //   ...

    //        // 不是常量，则不作为常量转换处理。
    //        if (fromConstant == null) {
    //            return false;
    //        }

    //        // null -> *
    //        if (fromConstant == NullConstant.@default) {
    //            return true;
    //        }

    //        switch (to.primitiveType) {
    //            case PrimitiveType.@byte:
    //                switch (fromConstant.resolvedType.primitiveType) {
    //                    case PrimitiveType.int16:
    //                    case PrimitiveType.uint16:
    //                    case PrimitiveType.int32:
    //                        return byte.MinValue <= fromConstant.int32Value && fromConstant.int32Value <= byte.MaxValue;
    //                    case PrimitiveType.uint32:
    //                        return fromConstant.uint32Value <= byte.MaxValue;
    //                    case PrimitiveType.int64:
    //                        return byte.MinValue <= fromConstant.int64Value && fromConstant.int64Value <= byte.MaxValue;
    //                    case PrimitiveType.uint64:
    //                        return fromConstant.uint64Value <= byte.MaxValue;
    //                    default:
    //                        return false;
    //                }
    //            case PrimitiveType.int16:
    //                switch (fromConstant.resolvedType.primitiveType) {
    //                    case PrimitiveType.uint16:
    //                        return fromConstant.int32Value <= short.MaxValue;
    //                    case PrimitiveType.int32:
    //                        return short.MinValue <= fromConstant.int32Value && fromConstant.int32Value <= short.MaxValue;
    //                    case PrimitiveType.uint32:
    //                        return fromConstant.uint32Value <= short.MaxValue;
    //                    case PrimitiveType.int64:
    //                        return short.MinValue <= fromConstant.int64Value && fromConstant.int64Value <= short.MaxValue;
    //                    case PrimitiveType.uint64:
    //                        return fromConstant.uint64Value <= (ulong)short.MaxValue;
    //                    default:
    //                        return false;
    //                }
    //            case PrimitiveType.uint16:
    //                switch (fromConstant.resolvedType.primitiveType) {
    //                    case PrimitiveType.int16:
    //                        return ushort.MinValue <= fromConstant.int32Value;
    //                    case PrimitiveType.int32:
    //                        return ushort.MinValue <= fromConstant.int32Value && fromConstant.int32Value <= ushort.MaxValue;
    //                    case PrimitiveType.uint32:
    //                        return fromConstant.uint32Value <= ushort.MaxValue;
    //                    case PrimitiveType.int64:
    //                        return ushort.MinValue <= fromConstant.int64Value && fromConstant.int64Value <= ushort.MaxValue;
    //                    case PrimitiveType.uint64:
    //                        return fromConstant.uint64Value <= ushort.MaxValue;
    //                    default:
    //                        return false;
    //                }
    //            case PrimitiveType.int32:
    //                switch (fromConstant.resolvedType.primitiveType) {
    //                    case PrimitiveType.uint32:
    //                        return fromConstant.uint32Value <= int.MaxValue;
    //                    case PrimitiveType.int64:
    //                        return int.MinValue <= fromConstant.int64Value && fromConstant.int64Value <= int.MaxValue;
    //                    case PrimitiveType.uint64:
    //                        return fromConstant.uint64Value <= int.MaxValue;
    //                    default:
    //                        return false;
    //                }
    //            case PrimitiveType.uint32:
    //                switch (fromConstant.resolvedType.primitiveType) {
    //                    case PrimitiveType.int32:
    //                        return uint.MinValue <= fromConstant.uint32Value;
    //                    case PrimitiveType.int64:
    //                        return uint.MinValue <= fromConstant.int64Value && fromConstant.int64Value <= uint.MaxValue;
    //                    case PrimitiveType.uint64:
    //                        return fromConstant.uint64Value <= uint.MaxValue;
    //                    default:
    //                        return false;
    //                }
    //            case PrimitiveType.int64:
    //                switch (fromConstant.resolvedType.primitiveType) {
    //                    case PrimitiveType.uint64:
    //                        return fromConstant.uint64Value <= long.MaxValue;
    //                    default:
    //                        return false;
    //                }
    //            case PrimitiveType.uint64:
    //                switch (fromConstant.resolvedType.primitiveType) {
    //                    case PrimitiveType.int64:
    //                        return (long)ulong.MinValue <= fromConstant.int64Value;
    //                    default:
    //                        return false;
    //                }

    //            // string -> char
    //            case PrimitiveType.@char:
    //                return fromConstant.resolvedType == PredefinedTypes.System_String;

    //            default:
    //                return false;
    //        }

    //    }

    //    /// <summary>
    //    /// 应用常量转换。
    //    /// </summary>
    //    /// <param name="fromConstant">要转换的常量值。</param>
    //    /// <param name="to">转换的目标类型。</param>
    //    /// <param name="srcNode">引发本次操作的源节点，主要用于报错。</param>
    //    /// <returns>返回代表转换操作的表达式。</returns>
    //    private static Expression applyImplicitConstantConversion(Constant fromConstant, TypeReference to, Node srcNode) {

    //        // null -> *
    //        if (fromConstant == NullConstant.@default) {
    //            return NullConstant.from(to);
    //        }

    //        switch (to.primitiveType) {
    //            case PrimitiveType.@byte:
    //            case PrimitiveType.int16:
    //            case PrimitiveType.uint16:
    //                return new SmallIntConstant(to, fromConstant.int32Value);
    //            case PrimitiveType.int32:
    //                return Int32Constant.from(fromConstant.int32Value);
    //            case PrimitiveType.uint32:
    //                return UInt32Constant.from(fromConstant.uint32Value);
    //            case PrimitiveType.int64:
    //                return Int64Constant.from(fromConstant.int64Value);
    //            case PrimitiveType.uint64:
    //                return UInt64Constant.from(fromConstant.uint64Value);
    //            case PrimitiveType.float32:
    //                return Float32Constant.from(fromConstant.float32Value);
    //            case PrimitiveType.float64:
    //                return Float64Constant.from(fromConstant.float64Value);
    //            case PrimitiveType.@bool:
    //                return fromConstant;
    //            case PrimitiveType.@char: {
    //                    string value = ((StringConstant)fromConstant).stringValue;
    //                    if (value == null || value.Length != 1) {
    //                        Compiler.error(ErrorCode.none, "字符常量应有且只有一个字符", srcNode);
    //                        return null;
    //                    }
    //                    return new SmallIntConstant(PredefinedTypes.System_Char, value[0]);
    //                }
    //            default:
    //                throw new Unreachable();
    //        }
    //    }

    //    /// <summary>
    //    /// 判断是否存在从指定类型到目标类型的隐式数值转换。
    //    /// </summary>
    //    /// <param name="from">转换的来源类型。</param>
    //    /// <param name="to">转换的目标类型。</param>
    //    /// <returns>如果存在则返回 true。</returns>
    //    private static bool hasImplicitNumericConversion(TypeReference from, TypeReference to) {
    //        switch (from.primitiveType) {
    //            case PrimitiveType.none:
    //                break;
    //            case PrimitiveType.int32:
    //                switch (to.primitiveType) {
    //                    case PrimitiveType.int64:
    //                    case PrimitiveType.uint64:
    //                    case PrimitiveType.float32:
    //                    case PrimitiveType.float64:
    //                        return true;
    //                }
    //                break;
    //            case PrimitiveType.uint32:
    //                switch (to.primitiveType) {
    //                    case PrimitiveType.int64:
    //                    case PrimitiveType.float32:
    //                    case PrimitiveType.float64:
    //                        return true;
    //                }
    //                break;
    //            case PrimitiveType.float32:
    //                switch (to.primitiveType) {
    //                    case PrimitiveType.float64:
    //                        return true;
    //                }
    //                break;
    //            case PrimitiveType.float64:
    //                break;
    //            case PrimitiveType.int64:
    //                switch (to.primitiveType) {
    //                    case PrimitiveType.float32:
    //                    case PrimitiveType.float64:
    //                        return true;
    //                }
    //                break;
    //            case PrimitiveType.uint64:
    //                switch (to.primitiveType) {
    //                    case PrimitiveType.float32:
    //                    case PrimitiveType.float64:
    //                        return true;
    //                }
    //                break;
    //            case PrimitiveType.int16:
    //                switch (to.primitiveType) {
    //                    case PrimitiveType.int32:
    //                    case PrimitiveType.uint32:
    //                    case PrimitiveType.int64:
    //                    case PrimitiveType.uint64:
    //                    case PrimitiveType.float32:
    //                    case PrimitiveType.float64:
    //                        return true;
    //                }
    //                break;
    //            case PrimitiveType.uint16:
    //                switch (to.primitiveType) {
    //                    case PrimitiveType.int32:
    //                    case PrimitiveType.int64:
    //                    case PrimitiveType.float32:
    //                    case PrimitiveType.float64:
    //                        return true;
    //                }
    //                break;
    //            case PrimitiveType.@byte:
    //                switch (to.primitiveType) {
    //                    case PrimitiveType.int16:
    //                    case PrimitiveType.uint16:
    //                    case PrimitiveType.int32:
    //                    case PrimitiveType.uint32:
    //                    case PrimitiveType.int64:
    //                    case PrimitiveType.uint64:
    //                    case PrimitiveType.float32:
    //                    case PrimitiveType.float64:
    //                        return true;
    //                }
    //                break;
    //        }

    //        return false;
    //    }

    //    /// <summary>
    //    /// 判断是否存在从指定类型到目标类型的字符转换。
    //    /// </summary>
    //    /// <param name="from">转换的来源类型。</param>
    //    /// <param name="to">转换的目标类型。</param>
    //    /// <returns>如果存在则返回 true。</returns>
    //    private static bool hasExplicitCharConversion(TypeReference from, TypeReference to) {
    //        if (from.primitiveType == PrimitiveType.@char) {
    //            switch (to.primitiveType) {
    //                case PrimitiveType.@byte:
    //                case PrimitiveType.int16:
    //                case PrimitiveType.uint16:
    //                case PrimitiveType.int32:
    //                case PrimitiveType.uint32:
    //                case PrimitiveType.int64:
    //                case PrimitiveType.uint64:
    //                case PrimitiveType.float32:
    //                case PrimitiveType.float64:
    //                    return true;
    //            }
    //        }
    //        return false;
    //    }

    //    /// <summary>
    //    /// 判断是否存在从指定类型到目标类型的隐式装箱转换。
    //    /// </summary>
    //    /// <param name="from">转换的来源类型。</param>
    //    /// <param name="to">转换的目标类型。</param>
    //    /// <returns>如果存在则返回 true。</returns>
    //    private static bool hasBoxingConversion(TypeReference from, TypeReference to) {
    //        if (from.isValueType) {

    //            // ValueType -> object/dynamic
    //            if (to == PredefinedTypes.System_Object || to == PredefinedTypes.@dynamic) {
    //                return true;
    //            }

    //            // ValueType -> interface
    //            if (to.memberType == MemberType.@interface && from.getAllRequiredTypes().Contains(to)) {
    //                return true;
    //            }

    //        }

    //        return false;
    //    }

    //    /// <summary>
    //    /// 判断是否存在从指定类型到目标类型的隐式类型转换。
    //    /// </summary>
    //    /// <param name="from">转换的来源类型。</param>
    //    /// <param name="to">转换的目标类型。</param>
    //    /// <returns>如果存在则返回 true。</returns>
    //    private static bool hasImplicitReferenceConversion(TypeReference from, TypeReference to) {

    //        // 非引用类型。
    //        if (from.isValueType || to.isValueType) {
    //            return false;
    //        }

    //        // * -> object/dynamic
    //        if (to == PredefinedTypes.System_Object || to == PredefinedTypes.dynamic) {
    //            return true;
    //        }

    //        // A -> BaseType/InterfaceType
    //        if (from.getAllRequiredTypes().Contains(to)) {
    //            return true;
    //        }

    //        // List<A> -> List<BaseType>
    //        if (from.genericParameters != null && to.genericParameterCount == from.genericParameterCount) {
    //            for (var i = 0; i < from.genericParameterCount; i++) {
    //                if (!hasImplicitReferenceConversion(from.genericParameters[i], to.genericParameters[i])) {
    //                    return false;
    //                }
    //            }
    //            return true;
    //        }

    //        return false;
    //    }

    //    /// <summary>
    //    /// 判断是否存在从指定类型到目标类型的显式接口转换。
    //    /// </summary>
    //    /// <param name="from">转换的来源类型。</param>
    //    /// <param name="to">转换的目标类型。</param>
    //    /// <returns>如果存在则返回 true。</returns>
    //    private static bool hasExplicitInterfaceConversion(TypeReference from, TypeReference to) {
    //        return to.memberType == MemberType.@interface && !from.isValueType;
    //    }

    //    /// <summary>
    //    /// 判断是否存在从指定类型到目标类型的指针到 void* 转换。
    //    /// </summary>
    //    /// <param name="from">转换的来源类型。</param>
    //    /// <param name="to">转换的目标类型。</param>
    //    /// <returns>如果存在则返回 true。</returns>
    //    private static bool hasImplicitPtrToVoidPtrConversion(TypeReference from, TypeReference to) {
    //        if (to.primitiveType == PrimitiveType.ptr && to.genericArguments[0] == PredefinedTypes.@void && (from.primitiveType == PrimitiveType.ptr || !from.isValueType)) {
    //            return true;
    //        }
    //        return false;
    //    }

    //    /// <summary>
    //    /// 判断是否存在从指定类型到目标类型的指针到指针的转换。
    //    /// </summary>
    //    /// <param name="from">转换的来源类型。</param>
    //    /// <param name="to">转换的目标类型。</param>
    //    /// <returns>如果存在则返回 true。</returns>
    //    private static bool hasExplicitPtrToPtrConversion(TypeReference from, TypeReference to) {
    //        if (from.primitiveType == PrimitiveType.ptr && to.primitiveType == PrimitiveType.ptr) {
    //            return true;
    //        }
    //        return false;
    //    }

    //    /// <summary>
    //    /// 判断是否存在从指定类型到目标类型的整数到指针的转换。
    //    /// </summary>
    //    /// <param name="from">转换的来源类型。</param>
    //    /// <param name="to">转换的目标类型。</param>
    //    /// <returns>如果存在则返回 true。</returns>
    //    private static bool hasExplicitIntegerToPtrConversion(TypeReference from, TypeReference to) {
    //        if (to.underlyingType == PredefinedTypes.System_Ptr_T) {
    //            switch (from.primitiveType) {
    //                case PrimitiveType.int64:
    //                case PrimitiveType.uint64:
    //                case PrimitiveType.int32:
    //                case PrimitiveType.uint32:
    //                    return true;
    //            }
    //        }
    //        return false;
    //    }

    //    /// <summary>
    //    /// 判断是否存在从指定类型到目标类型的用户自定义转换。
    //    /// </summary>
    //    /// <param name="from">转换的来源类型。</param>
    //    /// <param name="to">转换的目标类型。</param>
    //    /// <param name="implicitCall">是否允许进行隐式转换。</param>
    //    /// <returns>如果存在则返回 true。</returns>
    //    private static bool hasUserDefinedConversion(TypeReference from, TypeReference to, bool implicitCall) {
    //        UserDefinedConversionResolveResult result = new UserDefinedConversionResolveResult();
    //        resolveUserDefinedAsOperator(from, to, implicitCall, ref result);
    //        return result.type != UserDefinedConversionResolveResultType.noApplicableOperators && result.type != UserDefinedConversionResolveResultType.cannotImplicitCast;
    //    }

    //    private static Expression applyUserDefinedConversion(Expression fromExpression, TypeReference from, TypeReference to, bool implicitCall, Node srcNode) {
    //        UserDefinedConversionResolveResult result = new UserDefinedConversionResolveResult();
    //        resolveUserDefinedAsOperator(from, to, implicitCall, ref result);

    //        switch (result.type) {
    //            case UserDefinedConversionResolveResultType.applicableInNormalForm:
    //            case UserDefinedConversionResolveResultType.applicableInExtentedForm:
    //                fromExpression = ResolveHelper.convertTo(fromExpression, from, State.unset, srcNode);
    //                return ResolveHelper.convertTo(result.method.modifiers.hasFlag(Modifiers.@static) ? new ResolvedMethodInvocationExpression() {
    //                    target = result.method,
    //                    arguments = new Expression[] { fromExpression }
    //                } : new ResolvedMethodInvocationExpression() {
    //                    instance = fromExpression,
    //                    target = result.method
    //                }, to, State.unset, srcNode);
    //            case UserDefinedConversionResolveResultType.ambiguous:
    //                Compiler.error(ErrorCode.none, String.Format("无法确定此处调用“{0}”还是“{1}”", result.method.fullName, result.alt.fullName), srcNode);
    //                return null;
    //            default:
    //                throw new Unreachable();
    //        }

    //    }

    //    static void resolveUserDefinedAsOperator(TypeReference from, TypeReference to, bool implicitCall, ref UserDefinedConversionResolveResult result) {

    //        // 查找 to from.this as()
    //        var ops = from.getAllMembers("@as");
    //        if (ops != null) {
    //            foreach (MethodReference method in ops) {

    //                // 执行转换后的类型无法继续转为目标类型，忽略本重载。
    //                checkOperatorOverload(method, from, to, implicitCall, ref result);
    //            }
    //        }

    //        // 查找 static to to.this as(from)
    //        ops = to.getAllMembers("@as");
    //        if (ops != null) {
    //            foreach (MethodReference method in ops) {
    //                if (method.modifiers.hasFlag(Modifiers.@static)) {
    //                    checkOperatorOverload(method, from, to, implicitCall, ref result);
    //                }
    //            }
    //        }
    //    }

    //    private static void checkOperatorOverload(MethodReference method, TypeReference from, TypeReference to, bool implicitCall, ref UserDefinedConversionResolveResult result) {

    //        var methodFromType = method.modifiers.hasFlag(Modifiers.@static) ? method.parameters[0].type : method.parentType;
    //        var methodToType = method.returnType;

    //        // 无法转换为 from 或 to 类型，忽略操作。
    //        var fromConversion = ResolveHelper.classifyImplicitConversion(null, from, methodFromType);
    //        var toConversion = ResolveHelper.classifyImplicitConversion(null, methodToType, to);
    //        if (fromConversion == ConversionType.none || toConversion == ConversionType.none) {
    //            return;
    //        }

    //        // 检查隐式转换。
    //        if (implicitCall && method.getPredefinedAnnotation(PredefinedTypes.System_ImplicitAnnotation) == null) {
    //            result.method = method;
    //            result.type = UserDefinedConversionResolveResultType.cannotImplicitCast;
    //            return;
    //        }

    //        // 发现新的 applicableInNormalForm 结果。
    //        if (fromConversion == ConversionType.identity && toConversion == ConversionType.identity) {

    //            // 检查之前是否已找到匹配的项。
    //            if (result.method != null && result.type == UserDefinedConversionResolveResultType.applicableInNormalForm) {
    //                result.type = UserDefinedConversionResolveResultType.ambiguous;
    //                result.alt = method;
    //                return;
    //            }
    //            result.method = method;
    //            result.type = UserDefinedConversionResolveResultType.applicableInNormalForm;
    //            return;
    //        }

    //        // 发现新的 applicableInExtentedForm 结果。
    //        if (result.type == UserDefinedConversionResolveResultType.applicableInNormalForm) {
    //            return;
    //        }

    //        // 检查之前是否已找到匹配的项。
    //        if (result.method != null && result.type == UserDefinedConversionResolveResultType.applicableInExtentedForm) {
    //            result.type = UserDefinedConversionResolveResultType.ambiguous;
    //            result.alt = method;
    //            return;
    //        }

    //        result.method = method;
    //        result.type = UserDefinedConversionResolveResultType.applicableInExtentedForm;
    //    }

    //    /// <summary>
    //    /// 表示用户定义转换操作符解析结果。
    //    /// </summary>
    //    private struct UserDefinedConversionResolveResult {

    //        public UserDefinedConversionResolveResultType type;

    //        public MethodReference method;

    //        public MethodReference alt;

    //    }

    //    /// <summary>
    //    /// 指定用户自定义类型转换的结果类型。
    //    /// </summary>
    //    private enum UserDefinedConversionResolveResultType {

    //        /// <summary>
    //        /// 无可用的操作符重载。
    //        /// </summary>
    //        noApplicableOperators,

    //        /// <summary>
    //        /// 无法隐式转换。
    //        /// </summary>
    //        cannotImplicitCast,

    //        /// <summary>
    //        /// 存在转换的二义性。
    //        /// </summary>
    //        ambiguous,

    //        /// <summary>
    //        /// 以扩展的形式匹配。
    //        /// </summary>
    //        applicableInExtentedForm,

    //        /// <summary>
    //        /// 以普通形式匹配。
    //        /// </summary>
    //        applicableInNormalForm
    //    }

    //}

    /// <summary>
    /// 表示一个类型转换类型。
    /// </summary>
    public enum ConversionType {

        /// <summary>
        /// 没有可用的转换。
        /// </summary>
        none,

        /// <summary>
        /// 标识转换。
        /// </summary>
        identity,

        /// <summary>
        /// 隐式常量表达式转换。
        /// </summary>
        implicitConstant,

        /// <summary>
        /// 隐式数值转换。
        /// </summary>
        implicitNumeric,

        /// <summary>
        /// 装箱转换。
        /// </summary>
        boxing,

        /// <summary>
        /// 隐式引用转换。
        /// </summary>
        implicitReference,

        /// <summary>
        /// 指针到 void* 转换。
        /// </summary>
        ptrToVoidPtr,

        /// <summary>
        /// 用户定义的隐式转换。
        /// </summary>
        implicitUserDefined,

        /// <summary>
        /// 标记隐式转换。
        /// </summary>
        IMPILICT,

        /// <summary>
        /// 显式数值转换。
        /// </summary>
        explicitNumeric,

        /// <summary>
        /// 显式引用转换。
        /// </summary>
        explicitReference,

        /// <summary>
        /// 拆箱转换。
        /// </summary>
        unboxing,

        /// <summary>
        /// 指针到指针的转换。
        /// </summary>
        ptrToPtr,

        /// <summary>
        /// 整数到指针的转换。
        /// </summary>
        integerToPtr,

        /// <summary>
        /// 指针到整数的转换。
        /// </summary>
        ptrToInteger,

        /// <summary>
        /// 用户定义的显式转换。
        /// </summary>
        explicitUserDefined,

        /// <summary>
        /// 标记显式转换。
        /// </summary>
        EXPLICT,

    }

}